﻿using Furion;
using HiSport.Core;
using HiSport.Core.Entities;
using HiSport.Core.Entities.Auditing;
using SqlSugar;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Claims;

namespace HiSport.SqlSugar
{
    public class SqlSugarDb
    {
        public static SqlSugarScope Db { get; set; }

        public static SqlSugarScope SqlSugarScope(ConnectionConfig configConnection)
        {

            Db = new SqlSugarScope(configConnection, db =>
            {
                //全局过滤
                TableFilterItem(db);
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    //sql 执行前
                };
                db.Aop.OnLogExecuted = (sql, pars) =>
                {
                    Console.WriteLine(sql);
                    //sql 执行后
                };
                db.Aop.OnError = ex =>
                {
                    //sql 异常
                };
            });

            return Db;
        }

        #region 全局过滤器及配置
        /// <summary>
        /// 全局过滤
        /// </summary>
        private static void TableFilterItem(SqlSugarClient db)
        {
            //添加默认值
            DataExecuting(db);

            var types = Assembly.Load("HiSport.Core").GetTypes()
                               .Where(x => x.GetCustomAttribute<SugarTable>() != null
                                      && x.Namespace == "HiSport.Core.Entity");

            foreach (var entityType in types)
            {
                if (entityType.GetProperty("TenantId") != null)//判断实体类中包含属性
                {
                    //构建动态Lambda
                    var lambda = DynamicExpressionParser.ParseLambda
                    (new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(TenantEntity.TenantId)} ==  @0",
                        App.User?.FindFirstValue("TenantId"));
                    db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }

                if (entityType.GetProperty("IsDeleted") != null) //判断实体类中包含属性
                {
                    //构建动态Lambda
                    var lambda = DynamicExpressionParser.ParseLambda
                    (new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(FullAuditedEntity.IsDeleted)} ==  @0",
                        false);
                    db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }


                //if (entityType.GetProperty("OrgId") != null && CurrentUser.OrgId != 0) //判断实体类中包含属性
                //{
                //    //构建动态Lambda
                //    var lambda = DynamicExpressionParser.ParseLambda
                //    (new[] { Expression.Parameter(entityType, "it") },
                //        typeof(bool), $"@0.Contains({nameof(OrgEntity.OrgId)}) ", CurrentUser.UserDataAuth);
                //    db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                //}

            }

            //foreach (var entityType in types)
            //{
            //    db.EntityMaintenance.GetEntityInfo(entityType);
            //    if (entityType.GetProperty("TenantId") != null)//判断实体类中包含属性
            //    {
            //        //构建动态Lambda
            //        var lambda = DynamicExpressionParser.ParseLambda(entityType, typeof(object), "TenantId == @0", CurrentUser.TenantId);
            //        db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda)); //将Lambda传入过滤器

            //    };

            //    if (entityType.GetProperty("IsDeleted") != null) //判断实体类中包含属性
            //    {
            //        //构建动态Lambda
            //        db.QueryFilter.Add(new TableFilterItem<object>(entityType,
            //            DynamicExpressionParser.ParseLambda(entityType,
            //                typeof(object), "IsDeleted == @0", false))); //将Lambda传入过滤器
            //    }

            //}

        }
        /// <summary>
        /// 附默认值
        /// </summary>
        /// <param name="db"></param>
        private static void DataExecuting(SqlSugarClient db)
        {
            //全局字段赋值
            db.Aop.DataExecuting = (oldValue, entityInfo) =>
            {
                InsertByObject(entityInfo);
                UpdateByObject(oldValue, entityInfo);
            };

        }

        /// <summary>
        ///插入数据时附默认值
        /// </summary>
        /// <param name="entityInfo"></param>
        private static void InsertByObject(DataFilterModel entityInfo)
        {
            if (entityInfo.OperationType != DataFilterType.InsertByObject) return;
            switch (entityInfo.PropertyName)
            {
                case "CreatedTime":
                    entityInfo.SetValue(DateTime.Now);
                    break;
                case "CreatedBy":
                    entityInfo.SetValue(string.IsNullOrWhiteSpace(CurrentUser.Account) ? "" : CurrentUser.Account);
                    break;
                case "OrgId":
                    if (entityInfo.EntityName.ToLower() != "User".ToLower())
                    {
                        entityInfo.SetValue(CurrentUser.OrgId);
                    }
                    break;
                case "TenantId":

                    if (entityInfo.EntityName.ToLower() != "User".ToLower() || CurrentUser.TenantId > 0)
                    {
                        entityInfo.SetValue(CurrentUser.TenantId);
                    }
                    break;
            }
        }

        /// <summary>
        /// 修改数据时附默认值
        /// </summary>
        /// <param name="oldValue"></param>
        /// <param name="entityInfo"></param>
        private static void UpdateByObject(object oldValue, DataFilterModel entityInfo)
        {
            if (entityInfo.OperationType != DataFilterType.UpdateByObject) return;
            switch (entityInfo.PropertyName)
            {
                case "OrgId":
                    if (entityInfo.EntityName.ToLower() != "User".ToLower())
                    {
                        entityInfo.SetValue(CurrentUser.OrgId);
                    }
                    break;
                case "TenantId":
                    entityInfo.SetValue(CurrentUser.TenantId);
                    break;
            }
            if (entityInfo.PropertyName == "IsDeleted" && (bool)oldValue)
            {
                switch (entityInfo.PropertyName)
                {
                    case "DeletedTime":
                        entityInfo.SetValue(DateTime.Now);
                        break;
                    case "DeletedBy":
                        entityInfo.SetValue(CurrentUser.Account);
                        break;
                }
            }
            else
            {
                switch (entityInfo.PropertyName)
                {
                    case "ModifiedTime":
                        entityInfo.SetValue(DateTime.Now);
                        break;
                    case "ModifiedBy":
                        entityInfo.SetValue(CurrentUser.Account);
                        break;
                }
            }

        }
        #endregion
    }
}